
package com.zcp.wizard;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.database.SQLException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RemoteViews;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

public class Util {

    public static void exit(Context context) {
        Intent intent = new Intent(context, MyBroadcastReceiver.class);
        intent.setAction(Constants.EXIT_BROADCAST);
        context.sendBroadcast(intent);
    }

    /**
     * 获取SD卡信息,返回的值总大小和空闲大小。
     * 
     * @param context
     * @return
     */
    public static ArrayList<String[]> getSdInfo(Context ctx) {
        ArrayList<String[]> data = new ArrayList<String[]>();
        // linux把设备当作文件处理,从系统中获取SD设备
        File path = Environment.getExternalStorageDirectory();
        // 新建一个stat，它可以查看路径上面的系统文件
        StatFs stat = new StatFs(path.getPath());
        // 一个块的 有多少字节
        long blockSize = stat.getBlockSize();
        // 设备上有多少个空闲的块
        long availableBlock = stat.getAvailableBlocks();
        // 设备上所有的块
        long availableBlocks = stat.getBlockCount();
        Log.v("blockSize", String.valueOf(blockSize));
        Log.v("tag", String.valueOf(availableBlocks));
        // 换算成字节
        long availablePlace = availableBlock * blockSize;
        long placeCount = availableBlocks * blockSize;
        // 换算成GB 或 MB单位
        data.add(new String[] {
                ctx.getString(R.string.total), formatSize(placeCount, ctx)
        });
        data.add(new String[] {
                ctx.getString(R.string.free), formatSize(availablePlace, ctx)
        });
        return data;
    }

    /**
     * 获取内存信息。
     * 
     * @param ctx
     * @return
     */
    public static ArrayList<String[]> collectMemInfo(Context ctx) {
        ArrayList<String[]> data = new ArrayList<String[]>();

        BufferedReader reader = null;

        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(
                    "/proc/meminfo"))), //$NON-NLS-1$
                    1024);

            String line;
            String totalMsg = null;
            String freeMsg = null;
            String buffersMsg = null;
            String cachedMsg = null;
            String swapTotalMsg = null;
            String swapFreeMsg = null;

            while ((line = reader.readLine()) != null) {
                if (totalMsg == null && line.startsWith("MemTotal")) //$NON-NLS-1$
                {
                    totalMsg = line;
                } else if (freeMsg == null && line.startsWith("MemFree")) //$NON-NLS-1$
                {
                    freeMsg = line;
                } else if (buffersMsg == null && line.startsWith("Buffers")) //$NON-NLS-1$
                {
                    buffersMsg = line;
                } else if (cachedMsg == null && line.startsWith("Cached")) //$NON-NLS-1$
                {
                    cachedMsg = line;
                } else if (swapTotalMsg == null && line.startsWith("SwapTotal")) //$NON-NLS-1$
                {
                    swapTotalMsg = line;
                } else if (swapFreeMsg == null && line.startsWith("SwapFree")) //$NON-NLS-1$
                {
                    swapFreeMsg = line;
                }

                if (totalMsg != null && freeMsg != null && buffersMsg != null && cachedMsg != null
                        && swapTotalMsg != null && swapFreeMsg != null) {
                    break;
                }
            }

            long total = extractMemCount(totalMsg);
            long free = extractMemCount(freeMsg);
            long buffers = extractMemCount(buffersMsg);
            long cached = extractMemCount(cachedMsg);
            long swapTotal = extractMemCount(swapTotalMsg);
            long swapFree = extractMemCount(swapFreeMsg);

            ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
            MemoryInfo mi = new MemoryInfo();
            am.getMemoryInfo(mi);

            data.add(new String[] {
                    ctx.getString(R.string.total), formatSize(total, ctx)
            });
            data.add(new String[] {
                    ctx.getString(R.string.free) + ":", //$NON-NLS-1$
                    formatSize(mi.availMem, ctx)
            });
            data.add(new String[] {
                    ctx.getString(R.string.idle), formatSize(free, ctx)
            });
            data.add(new String[] {
                    ctx.getString(R.string.threshold), formatSize(mi.threshold, ctx)
            });
            data.add(new String[] {
                    ctx.getString(R.string.buffers), formatSize(buffers, ctx)
            });
            data.add(new String[] {
                    ctx.getString(R.string.cached), formatSize(cached, ctx)
            });
            data.add(new String[] {
                    ctx.getString(R.string.swap_total), formatSize(swapTotal, ctx)
            });
            data.add(new String[] {
                    ctx.getString(R.string.swap_free), formatSize(swapFree, ctx)
            });
        } catch (Exception e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ie) {
                    Log.e(TAG, ie.getLocalizedMessage(), ie);
                }
            }
        }

        return data;
    }

    /**
     * 读取数据，如MemTotal: 488616 kB 这一行中，把数据读出来，换算成byte单位。
     * 
     * @param line
     * @return
     */
    public static long extractMemCount(String line) {
        if (line != null) {
            int idx = line.indexOf(':');

            if (idx != -1) {
                line = line.substring(idx + 1).trim();

                idx = line.lastIndexOf(' ');

                if (idx != -1) {
                    String unit = line.substring(idx + 1);

                    try {
                        long size = Long.parseLong(line.substring(0, idx).trim());

                        if ("kb".equalsIgnoreCase(unit)) //$NON-NLS-1$
                        {
                            size *= 1024;
                        } else if ("mb".equalsIgnoreCase(unit)) //$NON-NLS-1$
                        {
                            size *= 1024 * 1024;
                        } else if ("gb".equalsIgnoreCase(unit)) //$NON-NLS-1$
                        {
                            size *= 1024 * 1024 * 1024;
                        } else {
                            Log.w(TAG, "Unexpected mem unit format: " + line); //$NON-NLS-1$
                        }

                        return size;
                    } catch (Exception e) {
                        Log.e(TAG, e.getLocalizedMessage(), e);
                    }
                } else {
                    Log.e(TAG, "Unexpected mem value format: " + line); //$NON-NLS-1$
                }
            } else {
                Log.e(TAG, "Unexpected mem format: " + line); //$NON-NLS-1$
            }
        }

        return -1;
    }

    /**
     * 获取系统存储，一个是总体的一个是空闲的。
     * 
     * @param ctx
     * @return
     */
    public static ArrayList<String[]> getSysMemoInfo(Context ctx) {

        ArrayList<String[]> data = new ArrayList<String[]>();
        // 获取root文件夹下面目录（系统文件夹）
        File path = Environment.getRootDirectory();
        if (path != null) {
            try {
                StatFs stat = new StatFs(path.getAbsolutePath());
                long blockSize = stat.getBlockSize();
                data.add(new String[] {
                        ctx.getString(R.string.total),
                        formatSize(stat.getBlockCount() * blockSize, ctx)
                });
                data.add(new String[] {
                        ctx.getString(R.string.free),
                        formatSize(stat.getAvailableBlocks() * blockSize, ctx)
                });
                return data;
            } catch (Exception e) {
                Log.e(Util.class.getName(), "Cannot access path: " //$NON-NLS-1$
                        + path.getAbsolutePath(), e);
            }
        }
        return data;
    }

    /**
     * 格式化数据(KB MB)。
     * 
     * @param size 单位是byte
     * @param ctx
     * @return
     */
    public static String formatSize(long size, Context ctx) {
        if (size == -1) {
            return ctx.getString(R.string.info_not_available);
        } else {
            return Formatter.formatFileSize(ctx, size);
        }
    }

    /**
     * 读取cpu的 工作时间和空闲时间。
     * 
     * @return [worktime, idletime]
     */
    public static long[] readCpuLoad() {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")), //$NON-NLS-1$
                    256);

            String line = reader.readLine();

            if (line != null && line.startsWith("cpu ")) //$NON-NLS-1$
            {
                line = line.substring(3).trim();

                StringTokenizer tokens = new StringTokenizer(line);

                long totaltime = 0, idletime = 0;
                int i = 0;
                String tk;

                while (tokens.hasMoreTokens() && i < 7) {
                    tk = tokens.nextToken();

                    if (i == 3) {
                        idletime = Long.parseLong(tk);
                    } else {
                        totaltime += Long.parseLong(tk);
                    }
                    i++;
                }

                return new long[] {
                        totaltime, idletime
                };
            }
        } catch (Exception e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    Log.e(TAG, e.getLocalizedMessage(), e);
                }
            }
        }

        return null;
    }

    /**
     * 读取cpu型号，和主频。
     * 
     * @return [model, mips]
     */
    public static String[] getCpuState() {
        BufferedReader reader = null;

        try {
            String line;
            String processor = null;
            String mips = null;
            String model = null;

            mips = readFile(F_SCALE_FREQ, //$NON-NLS-1$
                    true);

            // F_CPU_INFO 文件内容如下
            // Processor : ARMv7 Processor rev 2 (v7l)
            // BogoMIPS : 799.29
            // Features : swp half thumb fastmult vfp edsp neon vfpv3
            // CPU implementer : 0x41
            // CPU architecture: 7
            // CPU variant : 0x3
            // CPU part : 0xc08
            // CPU revision : 2
            //
            // Hardware : mapphone_UMTS
            // Revision : 0000
            // Serial : 0000000000000000
            // CPU Tier : 10
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(
                    F_CPU_INFO))), 1024);

            while ((line = reader.readLine()) != null) {
                if (processor == null && line.startsWith("Processor")) //$NON-NLS-1$
                {
                    processor = line;
                } else if (mips == null && line.startsWith("BogoMIPS")) //$NON-NLS-1$
                {
                    mips = line;
                }
                if (model == null && line.startsWith("model name")) //$NON-NLS-1$
                {
                    model = line;
                }

                if (model != null || (processor != null && mips != null)) {
                    break;
                }
            }

            if (model != null) {
                int idx = model.indexOf(':');
                if (idx != -1) {
                    return new String[] {
                            model.substring(idx + 1).trim(), null
                    };
                } else {
                    Log.e(TAG, "Unexpected processor format: " + model); //$NON-NLS-1$
                }
            } else if (processor != null && mips != null) {
                int idx = processor.indexOf(':');
                if (idx != -1) {
                    processor = processor.substring(idx + 1).trim();

                    idx = mips.indexOf(':');

                    if (idx != -1) {
                        mips = mips.substring(idx + 1).trim();
                    }

                    return new String[] {
                            processor, mips + "MHz" //$NON-NLS-1$
                    };
                } else {
                    Log.e(TAG, "Unexpected processor format: " + processor); //$NON-NLS-1$
                }
            } else {
                Log.e(TAG, "Incompatible cpu format"); //$NON-NLS-1$
            }
        } catch (Exception e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ie) {
                    Log.e(TAG, ie.getLocalizedMessage(), ie);
                }
            }
        }

        return null;
    }

    /**
     * 读取文件中数据。文件中数据只有一行，是数值数据。
     * 
     * @param fname 文件名称.
     * @param freq 是否转换成带有单位的。
     * @return
     */
    public static String readFile(String fname, boolean freq) {
        File f = new File(fname);

        if (f.exists() && f.isFile() && f.canRead()) {
            BufferedReader reader = null;
            String line;

            try {
                reader = new BufferedReader(new InputStreamReader(new FileInputStream(f)), 32);

                line = reader.readLine();

                if (line != null) {
                    if (freq) {
                        return String.valueOf(Long.parseLong(line.trim()) / 1000f) + "MHz"; //$NON-NLS-1$
                    } else {
                        return line.trim();
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, e.getLocalizedMessage(), e);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                        reader = null;
                    } catch (IOException ie) {
                        Log.e(TAG, ie.getLocalizedMessage(), ie);
                    }
                }
            }
        } else {
            Log.d(TAG, "Cannot read file: " + fname); //$NON-NLS-1$
        }

        return null;
    }

    /**
     * 单单查看电池电量信息
     * 
     * @param context
     */
    public static int[] getPowerInfo(Context context) {
        final int[] data = new int[5];
        BroadcastReceiver bcr = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
                    int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
                    int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
                    int temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
                    // 电池状态
                    int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
                            BatteryManager.BATTERY_STATUS_UNKNOWN);
                    boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
                    data[0] = level;
                    data[1] = scale;
                    data[2] = temp;
                    data[3] = status;
                    data[4] = present ? 1 : 0;
//                     Log.i("tag1",
//                     "level "+level+" scale "+scale+" temp "+temp+" status "+status);
//                     Log.i("tag1",
//                     " data[0] "+data[0]+" data[1] "+data[1]+" data[2] "+data[2]+" data[3] "+data[3]);

                }

            }
        };

        context.registerReceiver(bcr, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        // 等待一会儿，避免数据还没有读取就返回
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException ignored) {
        }
        return data;
    }

    /**
     * 转换温度显示格式。
     * 
     * @param temperature intent中获取的温度。
     * @param needUnit 是否带摄氏温度单位。
     * @return
     */
    public static String tranTemp(int temperature, boolean needUnit) {
        int tens = temperature / 10;

        String ct = Integer.toString(tens) + "." + (temperature - 10 * tens);
        return needUnit ? (ct + "\u00B0C ") : ct;

    }

    /**
     * 用来判断是否有包含 括号。
     * 
     * @param source
     * @return
     */
    public static boolean isHaveBracket(String source) {

        return (source != null && source.matches("\\[.+\\]"));
    }

    public static boolean getMobileNetworkState(Context context) {
        boolean status = false;
        try {
            ApnDAO apn = getDefaultAPN(context);
            boolean firstCheck = !isHaveBracket(apn.apn);
            ConnectivityManager sConnectivityManager = (ConnectivityManager) context
                    .getSystemService("connectivity");
            NetworkInfo networkInfo = sConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            status = networkInfo.isConnected() && firstCheck;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return status;
    }

    /**
     * 设置APN 如果原来apn<-->[apn],加挂号表示不可用
     * 
     * @param context
     */
    public static boolean toggleNetWork(Context context, boolean open) {
        boolean restult = false;
        // 这是单个的
        // try {
        // ApnDAO apn = getDefaultAPN(context);
        // String value = apn.apn;
        // Log.i("tag1", value);
        // if (isHaveBracket(value)) {
        // value = value.replace("[", "");
        // value = value.replace("]", "");
        // } else {
        // value = "[" + value + "]";
        // }
        // Log.i("tag1", value);
        // restult = setDefaultAPN(context, apn.id, value);
        //
        // } catch (Exception e) {
        // e.printStackTrace();
        // }
        // 解决只是修改当前选中的，如果当前显示有超过1个apn那么系统就会自动跳到第二个问题，造成关闭不了情况。
        try {
            LinkedList<ApnDAO> apnList = getCurrentAPN(context);

            for (ApnDAO element : apnList) {
                if (open) {
                    if (isHaveBracket(element.apn)) {
                        element.apn = element.apn.replace("[", "");
                        element.apn = element.apn.replace("]", "");
                    }
                } else {
                    if (!isHaveBracket(element.apn)) {
                        element.apn = "[" + element.apn + "]";
                    }
                }
                // Log.i("222", element.toString());
            }
            restult = setCurrentAPN(context, apnList);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return restult;

        // 切换移动网络(这个方法只是在[2.1.2.2]有效果，在2.3没有效果需要改近)
        // TelephonyManager sTelephonyManager = (TelephonyManager)
        // context.getSystemService("phone");
        // Class tmClass = sTelephonyManager.getClass();
        // boolean isConnected = getMobileNetworkState(context);
        // Log.i(TAG, "isConnected" + isConnected);
        // try {
        // Class[] arrayOfClass = new Class[] {};
        // Method getITelephonyMethod =
        // tmClass.getDeclaredMethod("getITelephony", arrayOfClass);
        // getITelephonyMethod.setAccessible(true);
        // Object ITelephonyObject = getITelephonyMethod
        // .invoke(sTelephonyManager, new Object[] {});
        // Class ITelephonyClass = ITelephonyObject.getClass();
        // Class[] parameterTypes = new Class[] {};
        // if (isConnected) {
        // Method disableConnectMethod =
        // ITelephonyClass.getMethod("disableDataConnectivity",
        // parameterTypes);
        // disableConnectMethod.invoke(ITelephonyObject, new Object[] {});
        // } else {
        // Method disableConnectMethod =
        // ITelephonyClass.getMethod("enableDataConnectivity",
        // parameterTypes);
        // disableConnectMethod.invoke(ITelephonyObject, new Object[] {});
        // }
        // } catch (Exception e) {
        // e.printStackTrace();
        // }

    }

    /*
     * 当前APN的URI
     */
    public static final Uri PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn");// 这是当前默认选中的apn

    public static final Uri APN_TABLE_URI = Uri.parse("content://telephony/carriers/current");// 这是当前显示的apn

    public static LinkedList<ApnDAO> getCurrentAPN(Context context) {
        LinkedList<ApnDAO> apnList = new LinkedList<ApnDAO>();
        ApnDAO apn = null;
        Cursor c = context.getContentResolver().query(APN_TABLE_URI, new String[] {
                "name", "apn", "_id"
        }, null, null, null);
        if (c != null) {
            if (c.moveToFirst()) {
                do {
                    apn = new ApnDAO();
                    apn.name = c.getString(c.getColumnIndex("name"));
                    apn.apn = c.getString(c.getColumnIndex("apn"));
                    apn.id = c.getInt(c.getColumnIndex("_id"));
                    apnList.add(apn);
                } while (c.moveToNext());
            }
            c.close();
        }
        return apnList;
    }

    /*
     * 设置指定id的APN的值
     */
    public static boolean setCurrentAPN(Context context, LinkedList<ApnDAO> apnList) {
        boolean result = true;
        ContentResolver resolver = context.getContentResolver();
        ContentValues values = null;
        int res = 0;

        for (ApnDAO element : apnList) {
            values = new ContentValues();

            values.put("apn", element.apn);

            try {
                res = resolver.update(APN_TABLE_URI, values, "_id=" + element.id, null);
                if (res != 1) {
                    result = false;
                }

            } catch (SQLException e) {
                Log.d(TAG, e.getMessage());
            }
            values = null;
        }

        return result;
    }

    public static ApnDAO getDefaultAPN(Context context) {
        ApnDAO apn = null;
        Cursor c = context.getContentResolver().query(PREFERRED_APN_URI, new String[] {
                "name", "apn", "_id"
        }, null, null, null);
        if (c != null) {
            if (c.moveToFirst()) {
                apn = new ApnDAO();
                apn.name = c.getString(c.getColumnIndex("name"));
                apn.apn = c.getString(c.getColumnIndex("apn"));
                apn.id = c.getInt(c.getColumnIndex("_id"));
            }
            c.close();
        }
        return apn;
    }

    /*
     * 设置指定id的APN的值
     */
    public static boolean setDefaultAPN(Context context, int id, String otherApn) {
        int res = -1;
        ContentResolver resolver = context.getContentResolver();
        ContentValues values = new ContentValues();

        values.put("apn", otherApn);
        try {
            res = resolver.update(APN_TABLE_URI, values, "_id=" + id, null);

        } catch (SQLException e) {
            Log.d(TAG, e.getMessage());
        }
        return (res == 1);
    }

    public static void closeThreeSwitcher(Context context) {
        if (WifiUtils.isEnable(context)) {
            WifiUtils.toggleWifi(context);
        }
        if (GpsUtils.isGPSEnable(context)) {
            GpsUtils.toggleGps(context, false);
        }
        if (BluetoothUtils.isEnabled()) {
            BluetoothUtils.toggleBluetooth(context);
        }
    }

    /**
     * 是否处于省电状态。
     * 
     * @param context
     * @return
     */
    public static boolean isGreenPrower(Context context) {
        boolean result = true;
        if (WifiUtils.isEnable(context)) {
            return false;
        }
        if (GpsUtils.isGPSEnable(context)) {
            return false;
        }
        if (BluetoothUtils.isEnabled()) {
            return false;
        }
        if (getScreenBrightness(context) > (255 * Constants.minBrightness)) {
            return false;
        }
        return result;

    }

    /**
     * 一键省电
     * 
     * @param context
     */
    public static void keyPower(Context context) {

        closeThreeSwitcher(context);

        Intent localIntent = new Intent(context, BrightnessSettingsActivity.class);
        localIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(localIntent);

    }

    public static int getProcessNumber(Context context) {
        int processNumber = 0;

        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        PackageManager pm = context.getPackageManager();
        List<RunningAppProcessInfo> raps = am.getRunningAppProcesses();

        if (raps == null) {
            return processNumber;
        }

        String self = context.getPackageName();
        String name;
        RunningAppProcessInfo rap;
        for (int i = 0, size = raps.size(); i < size; i++) {
            rap = raps.get(i);

            name = rap.processName;

            if (name.equals(self) || name.startsWith("com.google.process") //$NON-NLS-1$
                    || name.startsWith("com.android.phone") //$NON-NLS-1$
                    || name.startsWith("android.process") //$NON-NLS-1$
                    || name.startsWith("system") //$NON-NLS-1$
                    || name.startsWith("com.android.inputmethod") //$NON-NLS-1$
                    || name.startsWith("com.android.alarmclock")) //$NON-NLS-1$
            {
                continue;
            }
            try {
                pm.getApplicationInfo(name, PackageManager.GET_UNINSTALLED_PACKAGES);
            } catch (NameNotFoundException e) {
                continue;
            }
            processNumber++;
        }
        return processNumber;
    }

    /**
     * 一键释放内存
     * 
     * @param context
     */
    public static void freeMemory(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        List<RunningAppProcessInfo> raps = am.getRunningAppProcesses();

        if (raps == null) {
            return;
        }

        String self = context.getPackageName();

        String name;
        RunningAppProcessInfo rap;
        for (int i = 0, size = raps.size(); i < size; i++) {
            rap = raps.get(i);

            name = rap.processName;

            if (name.equals(self) || name.startsWith("com.google.process") //$NON-NLS-1$
                    || name.startsWith("com.android.phone") //$NON-NLS-1$
                    || name.startsWith("android.process") //$NON-NLS-1$
                    || name.startsWith("system") //$NON-NLS-1$
                    || name.startsWith("com.android.inputmethod") //$NON-NLS-1$
                    || name.startsWith("com.android.alarmclock")) //$NON-NLS-1$
            {
                continue;
            }

            if (rap.pkgList != null) {
                for (String pkg : rap.pkgList) {
                    if (pkg != null) {
                        am.restartPackage(pkg);

                    }
                }
            }
        }
    }

    /**
     * 获取内存信息
     * 
     * @param context
     * @return 
     *         返回字符串数组，数组长度为3，第一个为可用容量(带有单位，不能转为数字)，第二个为总容量(带有单位，不能转为数字)，第三个为使用率(
     *         可转为float类型)
     */
    public static String[] getMemoryInfo(Context context) {
        String[] info = new String[3];
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        MemoryInfo memoryInfo = new MemoryInfo();
        am.getMemoryInfo(memoryInfo);
        long availMem = memoryInfo.availMem;
        info[0] = Formatter.formatFileSize(context, availMem);

        String str1 = "/proc/meminfo";// 系统内存信息文件
        String str2;
        String[] arrayOfString;
        long totalMem = 0;

        try {
            FileReader localFileReader = new FileReader(str1);
            BufferedReader localBufferedReader = new BufferedReader(localFileReader, 8192);
            str2 = localBufferedReader.readLine();// 读取meminfo第一行，系统总内存大小

            arrayOfString = str2.split("\\s+");
            for (String num : arrayOfString) {
                Log.i(str2, num + "\t");
            }

            totalMem = Integer.valueOf(arrayOfString[1]).intValue() * 1024;// 获得系统总内存，单位是KB，乘以1024转换为Byte
            localBufferedReader.close();
            info[1] = Formatter.formatFileSize(context, totalMem);

        } catch (IOException e) {
        }

        info[2] = (float) (totalMem - availMem) / (float) totalMem + "";
        return info;
    }

    /**
     * 获取SD卡信息
     * 
     * @param context
     * @return 
     *         返回字符串数组，数组长度为3，第一个为可用容量(带有单位，不能转为数字)，第二个为总容量(带有单位，不能转为数字)，第三个为使用率(
     *         可转为float类型)
     */
    public static String[] getSdCardInfo(Context context) {

        String[] data = new String[3];
        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());

        long bytesAvailable = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();

        long byteTotal = (long) stat.getBlockCount() * (long) stat.getBlockSize();

        data[0] = Formatter.formatFileSize(context, bytesAvailable);
        data[1] = Formatter.formatFileSize(context, byteTotal);
        data[2] = (float) (byteTotal - bytesAvailable) / (float) byteTotal + "";

        return data;
    }

    /**
     * 获取手机内部存储信息
     * 
     * @param context
     * @return 
     *         返回字符串数组，数组长度为3，第一个为可用容量(带有单位，不能转为数字)，第二个为总容量(带有单位，不能转为数字)，第三个为使用率(
     *         可转为float类型)
     */
    public static String[] getStorageInfo(Context context) {

        String[] data = new String[3];
        StatFs stat = new StatFs(Environment.getDataDirectory().getPath());

        long bytesAvailable = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();

        long byteTotal = (long) stat.getBlockCount() * (long) stat.getBlockSize();

        data[0] = Formatter.formatFileSize(context, bytesAvailable);
        data[1] = Formatter.formatFileSize(context, byteTotal);
        data[2] = (float) (byteTotal - bytesAvailable) / (float) byteTotal + "";

        return data;
    }

    /**
     * 获取cpu的使用率
     * 
     * @return
     */
    public static float getCpuUsage() {
        try {
            RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
            String load = reader.readLine();

            String[] toks = load.split(" ");

            long idle1 = Long.parseLong(toks[5]);
            long cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                    + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

            try {
                Thread.sleep(360);
            } catch (Exception e) {
            }

            reader.seek(0);
            load = reader.readLine();
            reader.close();

            toks = load.split(" ");

            long idle2 = Long.parseLong(toks[5]);
            long cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                    + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);

            return (float) (cpu2 - cpu1) / ((cpu2 + idle2) - (cpu1 + idle1));

        } catch (IOException ex) {
            ex.printStackTrace();
        }

        return 0;
    }

    /**
     * 获取Cpu使用率
     * 
     * @return 返回字符串数组，第一个为使用率的百分数形式，第二个为最大CPU频率，第三个为使用率。
     */
    public static String[] getCpuInfo() {

        try {

            String cpuMax = readFile("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", //$NON-NLS-1$
                    true);
            int index = cpuMax.indexOf(".");
            if (index != -1) {
                cpuMax = cpuMax.substring(0, index) + "MHz";

            }

            float usage = getCpuUsage();
            String lable = String.format("%.2f%%", usage * 100);
            return new String[] {
                    lable, cpuMax, usage + ""

            };
        } catch (Exception e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
        }

        return null;
    }

    /**
     * 计算系统得分
     * 
     * @param memoryUsage 内存使用率
     * @param storgeUsage 手机存储使用率
     * @param sdcardUsage SD卡使用率
     * @return
     */
    public static int calculateScore(float memoryUsage, float storageUsage, float sdcardUsage) {
        int score = 50;
        if (memoryUsage > 0 && memoryUsage <= 1) {
            score += (int) ((1 - memoryUsage - 0.2) * (100 * 1));
        }
        if (storageUsage > 0 && storageUsage <= 1) {
            score += (int) ((1 - storageUsage) * (100 * 0.075));
        }
        if (sdcardUsage > 0 && sdcardUsage <= 1) {
            score += (int) ((1 - sdcardUsage) * (100 * 0.025));
        }
        if (score > 100) {
            score = 100;
        }
        return score;
    }

    /**
     * 设置widget中电池图片。
     * 
     * @param power
     * @param batteryImageView
     */
    public static void updateImageViewBatteryPic(int power, RemoteViews batteryImageView) {

        batteryImageView.setViewVisibility(R.id.imgBattery_0, View.GONE);
        for (int id : Constants.batteryPowerIds) {
            batteryImageView.setViewVisibility(id, View.GONE);// 这个是不占布局空间的
        }

        if (power < 20) {
            batteryImageView.setViewVisibility(R.id.imgBattery_10, View.VISIBLE);
        }

        for (int i = (batteryIndex.length - 1); i > 0; i--)// 从20-100开始判断
        {
            if (power >= batteryIndex[i])// 判断当前在那个电量区间
            {
                batteryImageView.setViewVisibility(Constants.batteryPowerIds[i], View.VISIBLE);
                break;
            }
        }
    }

    // 温度刻度图标的id
    private static int[] batteryTempIds = new int[] {
            R.id.wgTempDegree1, R.id.wgTempDegree2, R.id.wgTempDegree3, R.id.wgTempDegree4,
            R.id.wgTempDegree5, R.id.wgTempDegree6, R.id.wgTempDegree7, R.id.wgTempDegree8,
            R.id.wgTempDegree9, R.id.wgTempDegree10
    };

    // 电量和温度刻度值
    private static int[] batteryIndex = new int[] {
            10, 20, 30, 40, 50, 60, 70, 80, 90, 100
    };

    /**
     * 更新widget上面的温度指数。
     * 
     * @param tempFloat
     * @param rv
     */
    public static void updateWidgetTempPic(float tempFloat, RemoteViews rv) {
        int tempInt = ((int) (tempFloat / 10 + 0.5f)) * 10;// 对个位四舍五入
        // Log.i("tag", "tem"+tempInt);
        for (int id : batteryTempIds) {
            rv.setViewVisibility(id, View.INVISIBLE);// 这个是占布局空间的
        }

        for (int i = 0; i < batteryIndex.length; i++) {
            if (tempInt <= batteryIndex[i])// 判断当前在那个温度区间
            {
                for (int j = 0; j <= i; j++)// 在这个温度区间的图片都要设置可见
                {
                    rv.setViewVisibility(batteryTempIds[j], View.VISIBLE);
                }

                break;
            }
        }
    }

    /**
     * 更新widget上面的温度指数。
     * 
     * @param tempFloat
     * @param rv
     */
    public static void updateWidgetTempText(float tempFloat, RemoteViews rv, Context context) {
        if (tempFloat <= Constants.TEMPERATURE_GREEN) {
            rv.setTextColor(R.id.txtTemperature, context.getResources().getColor(R.color.green));
        } else if (tempFloat <= Constants.TEMPERATURE_YELLOW) {
            rv.setTextColor(R.id.txtTemperature, context.getResources().getColor(R.color.yellow));
        } else {
            rv.setTextColor(R.id.txtTemperature, context.getResources().getColor(R.color.red));
        }

    }

    /**
     * 根据温度和电量更新widget上面的文字和它颜色
     * 
     * @param status 电池状态
     * @param pow 电量[0,100]
     * @param tempFloat[0,100]
     * @param rv
     * @param context
     */
    public static void updateWidgetTip(int status, int pow, float tempFloat, RemoteViews rv,
            Context context, boolean present) {

        if (!present) {
            rv.setViewVisibility(R.id.txtBtryDialog, View.INVISIBLE);
            return;
        }
         Log.i("tag", "update the widget[" + pow + "][" + tempFloat + "] [" +
         status);
        rv.setViewVisibility(R.id.txtBtryDialog, View.INVISIBLE);
        // TODO 颜色阈值不对 5.1.1
        if (pow <= Constants.POW_RED) {
            rv.setViewVisibility(R.id.txtBtryDialog, View.VISIBLE);
            if (Util.isGreenPrower(context)) {
                setRemoteText(R.id.txtBtryDialog, context.getResources().getColor(R.color.red),
                        context.getString(R.string.widget_battery_not_full), rv);
            } else {
                setRemoteText(R.id.txtBtryDialog, context.getResources().getColor(R.color.red),
                        context.getString(R.string.widget_battery_tips_bad), rv);
            }
        }
        switch (status) {
            case BatteryManager.BATTERY_STATUS_CHARGING:
                rv.setViewVisibility(R.id.txtBtryDialog, View.VISIBLE);
                setRemoteText(R.id.txtBtryDialog,
                        context.getResources().getColor(R.color.text_other_color),
                        context.getString(R.string.widget_battery_changing), rv);
                break;
            case BatteryManager.BATTERY_STATUS_DISCHARGING:
                break;
            case BatteryManager.BATTERY_STATUS_FULL:
                rv.setViewVisibility(R.id.txtBtryDialog, View.VISIBLE);
                setRemoteText(R.id.txtBtryDialog,
                        context.getResources().getColor(R.color.text_other_color),
                        context.getString(R.string.widget_battery_full), rv);
                break;
            case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
                break;
        }
        // 优先级高于电量的
        if (tempFloat >= Constants.TEMPERATURE_YELLOW) {

            rv.setViewVisibility(R.id.txtBtryDialog, View.VISIBLE);
            setRemoteText(R.id.txtBtryDialog,
                    context.getResources().getColor(R.color.text_other_color),
                    context.getString(R.string.widget_battery_tips_hot), rv);
        }

    }

    /**
     * 设置remoteTextView 中的文字和颜色。
     * 
     * @param id
     * @param color
     * @param text
     * @param rv
     */
    public static void setRemoteText(int id, int color, String text, RemoteViews rv) {
        rv.setViewVisibility(id, View.VISIBLE);
        rv.setTextColor(id, color);
        rv.setTextViewText(id, text);
    }

    /**
     * 根据电池状态变化更新。
     * 
     * @param status
     * @param rv
     */
    public static void undateWidgetBatteryStatus(int status, RemoteViews rv, Context context,
            boolean present) {
        if (!present) {
            rv.setViewVisibility(R.id.imgBattery_charged, View.GONE);
            rv.setViewVisibility(R.id.imgBattery_charging, View.GONE);
            return;
        }
        switch (status) {
            case BatteryManager.BATTERY_STATUS_CHARGING: {
                rv.setViewVisibility(R.id.imgBattery_charged, View.GONE);
                rv.setViewVisibility(R.id.imgBattery_charging, View.VISIBLE);
                break;
            }
            case BatteryManager.BATTERY_STATUS_DISCHARGING: {
                rv.setViewVisibility(R.id.imgBattery_charged, View.GONE);
                rv.setViewVisibility(R.id.imgBattery_charging, View.GONE);
                break;
            }
            case BatteryManager.BATTERY_STATUS_FULL: {
                rv.setViewVisibility(R.id.imgBattery_charged, View.VISIBLE);
                rv.setViewVisibility(R.id.imgBattery_charging, View.GONE);
                break;
            }
            case BatteryManager.BATTERY_STATUS_NOT_CHARGING: {
                rv.setViewVisibility(R.id.imgBattery_charged, View.GONE);
                rv.setViewVisibility(R.id.imgBattery_charging, View.GONE);
                break;
            }
        }
    }

    public static void updateWidget(Context context, RemoteViews rv) {
        try {
            ComponentName localComponentName = new ComponentName(context, WidgetProvider.class);
            AppWidgetManager localAppWidgetManager = AppWidgetManager.getInstance(context);
            localAppWidgetManager.updateAppWidget(localComponentName, rv);
            return;
        } catch (Exception localException) {
            localException.printStackTrace();
        }
    }

    /**
     * 判断是否开启了自动亮度调节
     */
    public static boolean isAutoBrightness(ContentResolver aContentResolver) {
        boolean automicBrightness = false;
        try {
            automicBrightness = Settings.System.getInt(aContentResolver,
                    Constants.SCREEN_BRIGHTNESS_MODE) == Constants.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
        } catch (SettingNotFoundException e) {
            e.printStackTrace();
        }
        return automicBrightness;
    }

    /**
     * 获取屏幕的亮度
     */
    public static int getScreenBrightness(Context activity) {
        int nowBrightnessValue = 0;
        ContentResolver resolver = activity.getContentResolver();
        try {
            nowBrightnessValue = android.provider.Settings.System.getInt(resolver,
                    Settings.System.SCREEN_BRIGHTNESS, 255);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return nowBrightnessValue;
    }

    /**
     * @activity 如果这个是tabActivity下面的activity的话，就好获取tabActivity本身. 设置亮度
     */
    public static void setBrightness(Activity activity, int brightness) {

        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
        lp.screenBrightness = 1.0f;
        Float tmpFloat = (float) brightness / 255;
        if (0 <= brightness && brightness <= 255) {
            // 设置获取最小值,不能设置为0要不然就全黑了
            if (tmpFloat < Constants.minBrightness) {
                tmpFloat = Constants.minBrightness;
            }
            lp.screenBrightness = tmpFloat;// 值范围是[0,1.0]
            activity.getWindow().setAttributes(lp);// 在tabActivity中需要获取父亲句柄进行操作，如果在单独的Activity就直接获取window可以了
        }

    }

    /**
     * @activity 如果这个是tabActivity下面的activity的话，就好获取tabActivity本身. 设置亮度
     */
    public static void setBrightness(Window window, int brightness) {

        WindowManager.LayoutParams lp = window.getAttributes();
        lp.screenBrightness = 1.0f;
        Float tmpFloat = (float) brightness / 255;
        if (0 <= brightness && brightness <= 255) {
            // 设置获取最小值,不能设置为0要不然就全黑了
            if (tmpFloat < Constants.minBrightness) {
                tmpFloat = Constants.minBrightness;
            }
            lp.screenBrightness = tmpFloat;// 值范围是[0,1.0]
            window.setAttributes(lp);// 在tabActivity中需要获取父亲句柄进行操作，如果在单独的Activity就直接获取window可以了
        }

    }

    /**
     * 停止自动亮度调节
     */
    public static void stopAutoBrightness(Context activity) {
        Settings.System.putInt(activity.getContentResolver(), Constants.SCREEN_BRIGHTNESS_MODE,
                Constants.SCREEN_BRIGHTNESS_MODE_MANUAL);
    }

    /**
     * 开启亮度自动调节
     * 
     * @param activity
     */
    public static void startAutoBrightness(Activity activity) {
        Settings.System.putInt(activity.getContentResolver(), Constants.SCREEN_BRIGHTNESS_MODE,
                Constants.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
    }

    /**
     * 同步setting数据库中亮度[25,254]
     */
    public static int updateBrightnessData(Context context, int brightness) {

        if (brightness > 255) {
            brightness = 254;
        }
        if (brightness <= 25) {
            brightness = 25;
        }
        // 把数据和Seting中相关数据库同步

        Uri uri = android.provider.Settings.System.getUriFor("screen_brightness");
        android.provider.Settings.System.putInt(context.getContentResolver(), "screen_brightness",
                brightness);
        context.getContentResolver().notifyChange(uri, null);

        int resultBrightness = Settings.System.getInt(context.getContentResolver(),
                Settings.System.SCREEN_BRIGHTNESS, -1);

        return resultBrightness;
    }

    /**
     * 判断是否显示tipActivity
     * 
     * @param context
     * @return
     */
    public static boolean isShowTipActivity(Context context) {
        boolean show = false;
        SharedPreferences share = context.getSharedPreferences(Constants.WIZARD_SETTINGS,
                Context.MODE_PRIVATE);
        Log.i("tag1", "DONT_SHOW_TIPS " + share.getInt(Constants.DONT_SHOW_TIPS, 0));

        Log.i("tag1", "HAVE_SET_WIDGET " + share.getInt(Constants.HAVE_SET_WIDGET, 0));
        if (share.getInt(Constants.DONT_SHOW_TIPS, 0) == 0) {
            if (share.getInt(Constants.HAVE_SET_WIDGET, 0) == 0) {
                show = true;
            }
        }
        return show;
    }

    public static boolean isInstallWidget(Context context) {
        boolean install = false;
        SharedPreferences share = context.getSharedPreferences(Constants.WIZARD_SETTINGS,
                Context.MODE_PRIVATE);
        install = (share.getInt(Constants.HAVE_SET_WIDGET, 0) == 1);
        return install;
    }

    public static final String F_CPU_INFO = "/proc/cpuinfo";

    public static final String F_SCALE_FREQ = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq";

    private static String TAG = "Util";
}
